package org.NooLab.glue.instances;

import org.NooLab.glue.components.BoardConnectorIntf;
import org.NooLab.glue.components.MessageBoardFactory;
import org.NooLab.glue.components.MessageBoardFactoryProperties;
import org.NooLab.glue.components.ParticipantsUpLinkConnectorIntf;
import org.NooLab.glue.components.UpLinkConnectorIntf;
import org.NooLab.utilities.logging.PrintLog;


public abstract class ParticipantUpLinkServiceAbs {

	// =================================

	// object references ..............

	ParticipantFactory participantFactory;
	MessageBoardFactory  mbf;
	MessageBoardFactoryProperties  factoryProperties;
	
	MessageBoardParticipant mbp;
	
	 
	
	MessageBoardParticipant instance ;
	
	ParticipantsUpLinkConnectorIntf upLinkProcedures ; // the callback acc. to the contracted interface
	BoardConnectorIntf  boardLinkProcedures ; 
	// both are inheriting UpLinkConnectorIntf
	
	// main variables / properties ....
	
	int periodLengthBetweenPolls = 3000 ;
	
	boolean isrunning = false ;
	boolean started = false;

	
	
	protected UplinkCheckEngine uplinkCheckEngine;
	
	// helper objects .................
	
	PrintLog out = new PrintLog(2,true);
	
	
	
	// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

	public ParticipantUpLinkServiceAbs(){
		
	}

	// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
	
	
	protected boolean startUplinkCheckEngine( String role ){
		boolean rB=false;
		
		
		uplinkCheckEngine = new UplinkCheckEngine( role );
		
		uplinkCheckEngine.delay(100) ;
		rB = ((uplinkCheckEngine != null) && (isrunning==true)) ;
		
		return rB;
	}

	
	public int getPeriodLengthBetweenPolls() {
		return periodLengthBetweenPolls;
	}


	public void setPeriodLengthBetweenPolls(int periodLengthBetweenPolls) {
		this.periodLengthBetweenPolls = periodLengthBetweenPolls;
	}


	public void stop(){
		isrunning = false;
		
	}
	
	// ========================================================================
	class UplinkCheckEngine implements Runnable{
		
		String role ="";
		String thrdName="";
		Thread uceThrd ;
		
		public UplinkCheckEngine( String role){
		
			this.role = role.toLowerCase() ;
			thrdName = "UplinkCheckEngine-"+role;
			uceThrd = new Thread(this, thrdName) ;
			
			if (role.contains("source")){
				uceThrd.setPriority( Thread.NORM_PRIORITY + 2);
			}
			uceThrd.start() ;
		}

		
		@SuppressWarnings("static-access")
		private void delay(int millis){
			try {
					Thread.currentThread().sleep(millis);
			} catch (Exception e) {}
		}
		
		
		public void run() {
			int z;
			
			isrunning = true;
			
			try{
				
				z=0;
				while (isrunning){
					if (z<=1){
						delay(300);
					}else{
						delay(periodLengthBetweenPolls); 
					}
					
					// note that IBOARDs need not to check themselves, boards will return relayed transactions directly !!
					
					// upLinkProcedures.checkAvailability();
					// whether the check will be sent out or not is completely controlled by the called method 
					if (role.toLowerCase().contains("source")){
						if (upLinkProcedures!=null){
							upLinkProcedures.checkForResults(z);
						}
					}
					if (role.toLowerCase().contains("recept")){
						if (upLinkProcedures!=null){
							upLinkProcedures.checkForTasks(z) ;
						}
					}

					if (role.toLowerCase().contentEquals("board")){
						if (boardLinkProcedures!=null){
							boardLinkProcedures.checkForBoards(z) ;
						}
					}	
					// int r = upLinkProcedures.getExitValue() ;
 				
					z++;
					if (z>1000000){
						z=1;
					}
				}
				
			}catch(Exception ex){
				ex.printStackTrace();
			}
			
			out.printErr(3,"process <"+thrdName+"> has been stopped...");
		} // run()
		
	} // UplinkCheckEngine
	
}
